package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.common.constans.MqConstant;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.JsonUtil;
import com.atguigu.gmall.feign.cart.CartFeign;
import com.atguigu.gmall.feign.pay.PayFeign;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentWay;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.to.order.OrderCreateTo;
import com.atguigu.gmall.model.to.ware.*;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.service.OrderDetailService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;

import java.util.Date;

import com.atguigu.gmall.model.activity.CouponInfo;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.atguigu.gmall.common.constans.RedisConstant;
import com.atguigu.gmall.common.execption.GmallException;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.util.AuthUtil;
import com.atguigu.gmall.feign.user.UserFeign;
import com.atguigu.gmall.feign.ware.WareFeign;
import com.atguigu.gmall.model.cart.CartItem;
import com.atguigu.gmall.model.to.UserAuthTo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.model.vo.order.CartItemForOrderVo;
import com.atguigu.gmall.model.vo.order.OrderSubmitVo;

import com.atguigu.gmall.feign.product.ProductFeign;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.vo.order.OrderConfirmVo;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import groovyjarjarpicocli.CommandLine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

/**
 *
 */
@Slf4j
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo>
        implements OrderInfoService {
    @Autowired
    ProductFeign productFeign;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    UserFeign userFeign;
    @Autowired
    WareFeign wareFeign;
    @Qualifier("coreThreadPool")
    @Autowired
    ThreadPoolExecutor coreThreadPool;
    @Autowired
    CartFeign cartFeign;
    @Autowired
    OrderInfoMapper orderInfoMapper;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    PayFeign payFeign;
    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Override
    public OrderConfirmVo orderConfirm() {
        UserAuthTo authTo = AuthUtil.getAuthTo();
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        //底层是利用ThreadLocal来获取request对象，所以这里要用RequestContextHolder来获取
        RequestAttributes oldReq = RequestContextHolder.getRequestAttributes();
        CompletableFuture<Void> future1 = CompletableFuture.supplyAsync(() -> {
            RequestContextHolder.setRequestAttributes(oldReq);
            //获取用户购物车中勾选的商品信息
            List<CartItemForOrderVo> cartItemForOrderVoList = getDetailArrayList(authTo.getUserId());
            orderConfirmVo.setDetailArrayList(cartItemForOrderVoList);
            return cartItemForOrderVoList;
        }, coreThreadPool).thenAcceptAsync(cartItemForOrderVoList -> {
            //计算总件数
            Integer totalNum = getTotalNum(cartItemForOrderVoList);
            orderConfirmVo.setTotalNum(totalNum);
        }, coreThreadPool);

        CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(oldReq);
            //计算总金额
            BigDecimal totalAmount = getTotalAmount(authTo.getUserId());
            orderConfirmVo.setTotalAmount(totalAmount);
        }, coreThreadPool);
        CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(oldReq);
            //获取用户地址信息
            List<UserAddress> userAddressList = getUserAddressList();
            orderConfirmVo.setUserAddressList(userAddressList);
            String tradeNo = generateTradeNo();
            orderConfirmVo.setTradeNo(tradeNo);
        }, coreThreadPool);
        CompletableFuture.allOf(future1, future2, future3).join();//阻塞等待所有任务完成

        return orderConfirmVo;
    }

    //提交订单
    @Override
    public Long submitOrder(String tradeNo, OrderSubmitVo orderSubmitVo) {

        //1.验证交易号是否重复提交
        Boolean tradeNoFlag = validateTradeNo(tradeNo);
        if (!tradeNoFlag) {
            throw new GmallException(ResultCodeEnum.ORDER_REPEATE_SUBMIT_ERROR);
        }
        //2.校验价格是否一致
        Boolean priceFlag = validatePrice(orderSubmitVo);
        if (!priceFlag) {
            throw new GmallException(ResultCodeEnum.ORDER_PRICE_ERROR);
        }
        //3.验证库存
        validateStock(orderSubmitVo);
        //4.创建订单并插入数据库
        //4.1. 删除购物车中已选中的商品
        //4.2. 通知orderInfo更改订单状态为close(关单)
        Long orderId = saveOrder(orderSubmitVo, tradeNo);

        return orderId;
    }

    @Override
    @Transactional
    public Long saveOrder(OrderSubmitVo orderSubmitVo, String tradeNo) {
        //准备orderInfo对象
        OrderInfo orderInfo = prepareOrderInfo(orderSubmitVo);
        orderInfoMapper.insert(orderInfo);
        Long orderId = orderInfo.getId();
        //准备orderDetailList
        List<OrderDetail> orderDetailList = prepareOrderDetailList(orderId);
        orderDetailService.saveBatch(orderDetailList);

        //删除购物车中已选中的商品
        RequestAttributes oldReq = RequestContextHolder.getRequestAttributes();
        coreThreadPool.submit(() -> {
            RequestContextHolder.setRequestAttributes(oldReq);
            cartFeign.deleteChecked();
        });
        //通知orderInfo更改订单状态为close
        sendOrderClose(orderId);

        return orderId;
    }

    private void sendOrderClose(Long orderId) {
        Long userId = AuthUtil.getAuthTo().getUserId();
        OrderCreateTo orderCreateTo = new OrderCreateTo(orderId, userId);
        rabbitTemplate.convertAndSend(MqConstant.ORDER_EVENT_EXCHANGE,
                MqConstant.ORDER_CREATE_ROUTING_KEY
                , JsonUtil.toStr(orderCreateTo));
        log.info("订单创建消息已发送，消息内容：{}", orderCreateTo);
    }

    private List<OrderDetail> prepareOrderDetailList(Long id) {
        Long userId = AuthUtil.getAuthTo().getUserId();

        List<CartItem> checkedCartItems = getCheckedCartItems(userId);
        List<OrderDetail> orderDetailList = checkedCartItems.stream().map(
                cartItem -> {
                    OrderDetail orderDetail = new OrderDetail();
                    orderDetail.setOrderId(id);
                    orderDetail.setUserId(userId);
                    orderDetail.setSkuId(cartItem.getSkuId());
                    orderDetail.setSkuName(cartItem.getSkuName());
                    orderDetail.setImgUrl(cartItem.getSkuDefaultImg());
                    BigDecimal skuInfoPrice = productFeign.getSkuInfoPrice(cartItem.getSkuId());
                    orderDetail.setOrderPrice(skuInfoPrice);
                    orderDetail.setSkuNum(cartItem.getSkuNum());
                    //能到这里说明库存足够，无需再次判断库存
                    orderDetail.setHasStock("1");
                    orderDetail.setCreateTime(new Date());
                    orderDetail.setSplitTotalAmount(new BigDecimal("0"));
                    orderDetail.setSplitActivityAmount(new BigDecimal("0"));
                    orderDetail.setSplitCouponAmount(new BigDecimal("0"));
                    return orderDetail;
                }
        ).collect(Collectors.toList());

        return orderDetailList;
    }

    private OrderInfo prepareOrderInfo(OrderSubmitVo orderSubmitVo) {
        Long userId = AuthUtil.getAuthTo().getUserId();
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setConsignee(orderSubmitVo.getConsignee());
        orderInfo.setConsigneeTel(orderSubmitVo.getConsigneeTel());
        //总金额
        List<CartItem> checkedCartItems = getCheckedCartItems(userId);
        BigDecimal decimal = checkedCartItems.stream().
                map(cartItem -> {
                    BigDecimal skuInfoPrice = productFeign.getSkuInfoPrice(cartItem.getSkuId());
                    return skuInfoPrice.multiply(new BigDecimal(cartItem.getSkuNum().toString()));
                }).reduce(BigDecimal::add).get();
        orderInfo.setTotalAmount(decimal);
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        orderInfo.setUserId(userId);
        orderInfo.setPaymentWay(PaymentWay.ONLINE.name());
        orderInfo.setDeliveryAddress(orderSubmitVo.getDeliveryAddress());
        orderInfo.setOrderComment(orderSubmitVo.getOrderComment());

        //生成订单号
        String outTradeNo = generateOutTradeNo(userId);
        orderInfo.setOutTradeNo(outTradeNo);
        //订单详情
        String tradeBody = orderSubmitVo.getOrderDetailList().stream()
                .map(CartItemForOrderVo::getSkuName)
                .reduce((a, b) -> a + ";" + b)
                .get();
        orderInfo.setTradeBody(tradeBody);
        orderInfo.setCreateTime(new Date());
        //失效时间
        Long expireTime = System.currentTimeMillis() + 30 * 60 * 1000; // 30分钟过期

        orderInfo.setExpireTime(new Date(expireTime));

        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        //物流信息
        orderInfo.setTrackingNo("");
        //拆单的父子订单id
        orderInfo.setParentOrderId(0L);
        orderInfo.setImgUrl(orderSubmitVo.getOrderDetailList().get(0).getImgUrl());

        //orderInfo.setOrderDetailList(Lists.newArrayList());
        orderInfo.setWareId("");
        orderInfo.setProvinceId(0L);
        orderInfo.setActivityReduceAmount(new BigDecimal("0"));
        orderInfo.setCouponAmount(new BigDecimal("0"));
        orderInfo.setOriginalTotalAmount(new BigDecimal("0"));
        //可退款时间
        orderInfo.setRefundableTime(null);
        orderInfo.setFeightFee(new BigDecimal("0"));
        orderInfo.setOperateTime(new Date());
        //orderInfo.setOrderDetailVoList(Lists.newArrayList());
        orderInfo.setCouponInfo(new CouponInfo());
//        orderInfo.setId(0L); 自增id由数据库生成
        return orderInfo;
    }

    //订单交易编号（第三方支付用)
    @Override
    public String generateOutTradeNo(Long userId) {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6); //生成6位随机字符串
        String timeStamp = String.valueOf(System.currentTimeMillis());
        return "GMALL-" + timeStamp + "-" + userId + "-" + uuid;
    }

    private void validateStock(OrderSubmitVo orderSubmitVo) {
        List<CartItem> checkedCartItems = getCheckedCartItems(AuthUtil.getAuthTo().getUserId());
        List<String> noStockSkus = new ArrayList<>();
        checkedCartItems.stream().forEach(cartItem -> {
            String hasStock = wareFeign.hasStock(cartItem.getSkuId(), cartItem.getSkuNum());
            //hasStock:0：无货  1：有货
            if ("0".equals(hasStock)) {
                noStockSkus.add("[" + cartItem.getSkuName() + "]");
            }
        });
        if (!noStockSkus.isEmpty()) {
            String msg = noStockSkus.stream()
                    .reduce((a, b) ->
                            a + "," + b
                    )
                    .get();
            throw new GmallException(msg + ":库存不足", ResultCodeEnum.ORDER_NOT_ENOUGH_STOCK.getCode());
        }

    }

    private Boolean validatePrice(OrderSubmitVo orderSubmitVo) {
        Long userId = AuthUtil.getAuthTo().getUserId();
        BigDecimal submitTotalAmount = orderSubmitVo.getOrderDetailList().stream()
                .map(cartItem -> {
                    return cartItem.getOrderPrice().multiply(new BigDecimal(cartItem.getSkuNum().toString()));
                }).reduce(BigDecimal::add).orElse(new BigDecimal("0"));
        List<CartItem> checkedCartItems = getCheckedCartItems(userId);
        BigDecimal cartTotalAmount = checkedCartItems.stream()
                .map(cartItem -> {
                    BigDecimal skuInfoPrice = productFeign.getSkuInfoPrice(cartItem.getSkuId());
                    return skuInfoPrice.multiply(new BigDecimal(cartItem.getSkuNum().toString()));
                }).reduce(BigDecimal::add).orElse(new BigDecimal("0"));
        return submitTotalAmount.compareTo(cartTotalAmount) == 0;
    }

    //生成随机的交易号
    //确认订单时生成交易号,返回给前端并存入redis中,供后续支付时校验
    //前端提交订单时会携带交易号,后台和redis进行校验,校验通过后再进行支付
    //成功后删除redis中的交易号,可以防止重复提交订单
    public String generateTradeNo() {
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        redisTemplate.opsForValue().set(RedisConstant.ORDER_REPEATE_SUBMIT_PRE + token, "1", 60 * 10, TimeUnit.SECONDS);
        return token;
    }

    public Boolean validateTradeNo(String tradeNo) {
        String str = redisTemplate.opsForValue().get(RedisConstant.ORDER_REPEATE_SUBMIT_PRE + tradeNo);
        if (str == null) {
            return false;
        }
        //验证成功后删除redis中的交易号,删除需要原子性操作,所以不能使用delete方法,用lua脚本来实现原子性操作
        //redisTemplate.delete(RedisConstant.ORDER_REPEATE_SUBMIT_PRE + tradeNo); //删除redis中的交易号
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long executed = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(RedisConstant.ORDER_REPEATE_SUBMIT_PRE + tradeNo), str);
        //lua脚本执行成功返回1,否则返回0
        return executed == 1L;
    }

    //获取用户地址信息
    private List<UserAddress> getUserAddressList() {
        List<UserAddress> userAddressList = userFeign.userAddress();
        return userAddressList;
    }

    private BigDecimal getTotalAmount(Long userId) {
        List<CartItem> checkedCartItems = getCheckedCartItems(userId);
        BigDecimal decimal = checkedCartItems.stream()
                .map(cartItem -> {
                    BigDecimal skuInfoPrice = productFeign.getSkuInfoPrice(cartItem.getSkuId());
                    return skuInfoPrice.multiply(new BigDecimal(cartItem.getSkuNum().toString()));
                }).reduce(BigDecimal::add)
                .orElse(new BigDecimal("0"));

        return decimal;
    }

    @Override
    //获取用户购物车中勾选的购物车项
    public List<CartItem> getCheckedCartItems(Long userId) {
        return cartFeign.getCheckedCartItems();
    }


    //关闭订单(未支付状态的订单关单)
    @Override
    public void closeOrder(OrderCreateTo orderCreateTo) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(orderCreateTo.getUserId());
        orderInfo.setId(orderCreateTo.getOrderId());
        orderInfo.setOrderStatus(ProcessStatus.CLOSED.name());
        orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
        orderInfoMapper.closeOrder(orderInfo, ProcessStatus.UNPAID.name());
        log.info("用户:{}的订单:{}已关闭", orderCreateTo.getUserId(), orderCreateTo.getOrderId());
    }

    @Override
    public OrderInfo infoById(Long orderId) {
        UserAuthTo authTo = AuthUtil.getAuthTo();
        Long userId = authTo.getUserId();
        LambdaQueryWrapper<OrderInfo> queryWrapper = Wrappers.lambdaQuery(OrderInfo.class)
                .eq(OrderInfo::getUserId, userId)
                .eq(OrderInfo::getId, orderId);

        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        return orderInfo;
    }

    //支付成功后修改订单状态为已支付
    @Override
    public void updateOrderStatusToPaid(String outTradeNo) {
        long userId = Long.parseLong(outTradeNo.split("-")[2]);
        orderInfoMapper.updateOrderStatusToPaid(userId, outTradeNo, ProcessStatus.PAID.name(), OrderStatus.PAID.name());
    }

    //根据支付宝的订单号查询订单状态,并修改订单状态
    @Override
    public void checkOrderStatusByAliPay(String outTradeNo) {
        long userId = Long.parseLong(outTradeNo.split("-")[2]);
        LambdaQueryWrapper<OrderInfo> queryWrapper = Wrappers.lambdaQuery(OrderInfo.class)
                .eq(OrderInfo::getUserId, userId)
                .eq(OrderInfo::getOutTradeNo, outTradeNo);
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        //远程调用支付宝接口查询订单状态
        Result<String> stringResult = payFeign.checkOrderStatus(outTradeNo);
        if (stringResult.isOk()) {
            String tradeStatus = stringResult.getData();
            if ("TRADE_SUCCESS".equals(tradeStatus) && (OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) || OrderStatus.CLOSED.name().equals(orderInfo.getOrderStatus()))) {
                //修改订单状态为已支付
                orderInfoMapper.updateOrderStatusToPaid(userId, outTradeNo, ProcessStatus.PAID.name(), OrderStatus.PAID.name());
            }

        }
    }

    @Override
    public WareOrderTo prepareWareOrderTo(String outTradeNo) {
        long userId = Long.parseLong(outTradeNo.split("-")[2]);
        List<OrderInfo> orderInfos = orderInfoMapper.prepareWareOrderTo(userId, outTradeNo);
        OrderInfo orderInfo = orderInfos.get(0);
        WareOrderTo wareOrderTo = new WareOrderTo();
        wareOrderTo.setOrderId(orderInfo.getId());
        wareOrderTo.setConsignee(orderInfo.getConsignee());
        wareOrderTo.setConsigneeTel(orderInfo.getConsigneeTel());
        wareOrderTo.setOrderComment(orderInfo.getOrderComment());
        wareOrderTo.setOrderBody(orderInfo.getTradeBody());
        wareOrderTo.setDeliveryAddress(orderInfo.getDeliveryAddress());
        wareOrderTo.setPaymentWay(Objects.equals(orderInfo.getPaymentWay(), "ONLINE") ? "2" : "1");

        wareOrderTo.setWareId(orderInfo.getWareId());
        List<WareDetailsTo> wareDetailsToList = orderInfo.getOrderDetailList()
                .stream()
                .map((orderDetail -> {
                    WareDetailsTo wareDetailsTo = new WareDetailsTo();
                    wareDetailsTo.setSkuId(orderDetail.getSkuId());
                    wareDetailsTo.setSkuName(orderDetail.getSkuName());
                    wareDetailsTo.setSkuNum(orderDetail.getSkuNum());
                    return wareDetailsTo;
                })).collect(Collectors.toList());
        wareOrderTo.setDetails(wareDetailsToList);
        return wareOrderTo;
    }

    //拆单
    @Override
    public List<WareOrderTo> splitOrder(WareSplitVo wareSplitVo) {
        Long orderId = wareSplitVo.getOrderId();
        List<WareSkuVo> wareSkuMap = JsonUtil.jsonToObject(wareSplitVo.getWareSkuMap(), new TypeReference<List<WareSkuVo>>() {
        });
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        Long userId = orderInfo.getUserId();
        Long id = orderInfo.getId();
        //根据订单项查询订单详情列表
        LambdaQueryWrapper<OrderDetail> queryWrapper = Wrappers.lambdaQuery(OrderDetail.class)
                .eq(OrderDetail::getOrderId, id)
                .eq(OrderDetail::getUserId, userId);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(queryWrapper);
        Set<Long> skuIds = orderDetails.stream().map(OrderDetail::getSkuId).collect(Collectors.toSet());
        orderInfo.setOrderDetailList(orderDetails);

        List<WareOrderTo> wareOrderTos = wareSkuMap.stream().
                map(wareSkuVo -> {
                    String wareId = wareSkuVo.getWareId(); //仓库id
                    Set<Long> wareSkuIds = wareSkuVo.getSkuIds().stream().map(Long::parseLong).collect(Collectors.toSet()); //商品id列表
                    WareOrderTo wareOrderTo = prepareChildOrderAndSave(id, userId, wareId, wareSkuIds, orderInfo);
                    return wareOrderTo;
                }).collect(Collectors.toList());
        //修改父订单状态为拆单
        orderInfoMapper.updateOrderStatusToSplit(id, userId, ProcessStatus.SPLIT.name(), OrderStatus.SPLIT.name());

        return wareOrderTos;
    }
    //根据库存结果更新订单状态
    @Override
    public void updateOrderStatusByStock(WareStockStatusTo wareStockStatusTo) {
        String status = wareStockStatusTo.getStatus();
        String orderStauts = null;
        switch (status){
            case "DEDUCTED" :orderStauts=OrderStatus.WAITING_DELEVER.name(); break;
            case "OUT_OF_STOCK":orderStauts=OrderStatus.SCHEDULING.name(); break;
        }
        orderInfoMapper.updateOrderStatusByStock(wareStockStatusTo.getOrderId(), orderStauts,orderStauts);
    }

    private WareOrderTo prepareChildOrderAndSave(Long id, Long userId, String wareId, Set<Long> wareSkuIds, OrderInfo orderInfo) {
        //过滤出当前仓库下的子订单项skuId
        List<OrderDetail> childOrderDetailList = orderInfo.getOrderDetailList().stream()
                .filter(orderDetail -> wareSkuIds.contains(orderDetail.getSkuId()))
                .collect(Collectors.toList());
        //设置子订单的属性
        OrderInfo orderInfoChild = new OrderInfo();
        orderInfoChild.setConsignee(orderInfo.getConsignee());
        orderInfoChild.setConsigneeTel(orderInfo.getConsigneeTel());

        orderInfoChild.setOrderStatus(orderInfo.getOrderStatus());
        orderInfoChild.setUserId(userId);
        orderInfoChild.setPaymentWay(orderInfo.getPaymentWay());
        orderInfoChild.setDeliveryAddress(orderInfo.getDeliveryAddress());
        orderInfoChild.setOrderComment(orderInfo.getOrderComment());
        orderInfoChild.setOutTradeNo(orderInfo.getOutTradeNo());
        orderInfoChild.setTradeBody(childOrderDetailList.get(0).getSkuName());
        orderInfoChild.setCreateTime(new Date());
        orderInfoChild.setExpireTime(orderInfo.getExpireTime());
        orderInfoChild.setProcessStatus(orderInfo.getProcessStatus());
        orderInfoChild.setTrackingNo("");
        orderInfoChild.setParentOrderId(id);
        orderInfoChild.setImgUrl(childOrderDetailList.get(0).getImgUrl());
        orderInfoChild.setOrderDetailList(childOrderDetailList);
        orderInfoChild.setWareId(wareId);
        orderInfoChild.setProvinceId(0L);
        orderInfoChild.setActivityReduceAmount(new BigDecimal("0"));
        orderInfoChild.setRefundableTime(orderInfo.getRefundableTime());
        orderInfoChild.setFeightFee(new BigDecimal("0"));
        orderInfoChild.setOperateTime(new Date());
        orderInfoChild.setOrderDetailVoList(Lists.newArrayList());
        orderInfoChild.sumTotalAmount();
        //保存子订单,id由数据库生成
        orderInfoMapper.insert(orderInfoChild);
        //保存子订单详情
        List<OrderDetail> orderDetailList = orderInfoChild.getOrderDetailList();
        orderDetailList
                .stream()
                .forEach(orderDetail -> {
                    orderDetail.setOrderId(orderInfoChild.getId());
                });
        orderDetailService.saveBatch(orderDetailList);

        //构建子订单的返回
        WareOrderTo wareOrderTo = new WareOrderTo();
        wareOrderTo.setOrderId(orderInfoChild.getId());
        wareOrderTo.setConsignee(orderInfoChild.getConsignee());
        wareOrderTo.setConsigneeTel(orderInfoChild.getConsigneeTel());
        wareOrderTo.setOrderComment(orderInfoChild.getOrderComment());
        wareOrderTo.setOrderBody(orderInfoChild.getTradeBody());
        wareOrderTo.setDeliveryAddress(orderInfoChild.getDeliveryAddress());
        wareOrderTo.setPaymentWay(Objects.equals(orderInfoChild.getPaymentWay(), "ONLINE") ? "2" : "1");

        wareOrderTo.setWareId(orderInfoChild.getWareId());

        List<WareDetailsTo> wareDetailsToList = childOrderDetailList.stream()
                .map(orderDetail -> {
                    WareDetailsTo wareDetailsTo = new WareDetailsTo();
                    wareDetailsTo.setSkuId(orderDetail.getSkuId());
                    wareDetailsTo.setSkuNum(orderDetail.getSkuNum());
                    wareDetailsTo.setSkuName(orderDetail.getSkuName());
                    return wareDetailsTo;
                }).collect(Collectors.toList());

        wareOrderTo.setDetails(wareDetailsToList);
        return wareOrderTo;
    }

    private Integer getTotalNum(List<CartItemForOrderVo> cartItemForOrderVoList) {
        Integer integer = cartItemForOrderVoList.stream()
                .map(CartItemForOrderVo::getSkuNum)
                .reduce(Integer::sum)
                .orElse(0); //如果购物车为空，则返回0
        return integer;
    }

    //获取勾选的购物项
    private List<CartItemForOrderVo> getDetailArrayList(Long userId) {
        List<CartItem> cartItemList = getCheckedCartItems(userId);
        List<CartItemForOrderVo> cartItemForOrderVoList = cartItemList.stream()
                .map(cartItem -> {
                    CartItemForOrderVo orderVo = new CartItemForOrderVo();
                    orderVo.setSkuNum(cartItem.getSkuNum());
                    orderVo.setImgUrl(cartItem.getSkuDefaultImg());
                    orderVo.setSkuName(cartItem.getSkuName());
                    BigDecimal skuInfoPrice = productFeign.getSkuInfoPrice(cartItem.getSkuId());
                    orderVo.setOrderPrice(skuInfoPrice);
                    String hasStock = wareFeign.hasStock(cartItem.getSkuId(), cartItem.getSkuNum());
                    orderVo.setStock(hasStock);
                    return orderVo;
                }).collect(Collectors.toList());

        return cartItemForOrderVoList;
    }
}




